﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;
using CML.Intercamber.Business;
using CML.Intercamber.Business.Constants;
using CML.Intercamber.Business.Dao;
using CML.Intercamber.Business.Helper;
using CML.Intercamber.Business.Model;
using CML.Intercamber.Web.Helpers;
using CML.Intercamber.Web.Models;
using MvcJqGrid;

namespace CML.Intercamber.Web.Controllers
{
    public class AdminController : BaseController
    {
        #region gestion des textes

        private const string ResourcesDirectory = "~/App_GlobalResources/";

        public ActionResult Texts()
        {
            if (!ConnectedUserHelper.IsAdmin) return RedirectToAction("Login", "Account");
            ViewBag.AvailableLanguages = TextTranslator.ListLanguages(Server.MapPath(ResourcesDirectory));
            return View();
        }

        [HttpGet]
        public ActionResult TextsData(GridSettings gridSettings, string filter)
        {
            if (!ConnectedUserHelper.IsAdmin) return RedirectToAction("Login", "Account");
            string dir = Server.MapPath(ResourcesDirectory);
            var languages = TextTranslator.ListLanguages(dir);
            Dictionary<string, TextTranslator> textData = TextTranslator.LoadTextTranslators(dir, filter);

            //List<TextTranslatorGrid> resGrid = (from t in textData
            //    from l in languages
            //    orderby t.Key, l
            //    select new TextTranslatorGrid
            //    {
            //        Code = t.Key,
            //        Language = l,
            //        Label = t.Value.Translations.ContainsKey(l) ? t.Value.Translations[l] : ""
            //    }).ToList();

            var jsonSerialiser = new JavaScriptSerializer();

            int totalPages = 0;
            if (gridSettings.PageSize > 0)
                totalPages = (int)Math.Ceiling((decimal)textData.Count / gridSettings.PageSize);

            StringBuilder sb = new StringBuilder();
            sb.Append("{\"total\":");
            sb.Append(totalPages);
            sb.Append(",\"page\":");
            sb.Append(gridSettings.PageIndex);
            sb.Append(",\"records\":");
            sb.Append(textData.Count);
            sb.Append(",\"rows\":[");
            bool first = true;

            foreach (var txt in textData.OrderBy(x => x.Key).Skip(gridSettings.PageSize * (gridSettings.PageIndex - 1)).Take(gridSettings.PageSize))
            {
                if (!first)
                    sb.Append(",");
                sb.Append("{\"Code\":\"");
                sb.Append(txt.Key.Replace("\"", "\\\""));
                sb.Append("\"");
                foreach (var l in languages)
                {
                    sb.Append(",\"Text_");
                    sb.Append(l);
                    sb.Append("\":");
                    if (txt.Value.Translations.ContainsKey(l))
                        sb.Append(jsonSerialiser.Serialize(txt.Value.Translations[l].Replace("\"", "\\\"")));
                    else
                        sb.Append("\"\"");
                }
                sb.Append("}");
                first = false;
            }
            sb.Append("]}");
            return new ContentResult { Content = sb.ToString(), ContentType = "application/json", ContentEncoding = Encoding.UTF8 };
        }

        [HttpPost]
        [ValidateInput(false)]
        public JsonResult TextsEdit(FormCollection collection)
        {
            if (!ConnectedUserHelper.IsAdmin) return null;

            string dir = Server.MapPath(ResourcesDirectory);
            string code = Convert.ToString(collection["id"]);
            var languages = TextTranslator.ListLanguages(dir);
            foreach (var language in languages)
            {
                if (!string.IsNullOrEmpty(collection["Text_" + language]))
                    TextTranslator.UpdateText(language, code, collection["Text_" + language].Replace("\n", "\r\n"), dir);
            }
            return Json(true);
        }
        #endregion

        #region students invites

        public ActionResult StudentInvite()
        {
            if (!ConnectedUserHelper.IsAdmin && !ConnectedUserHelper.IsTeacher) return RedirectToAction("Login", "Account");

            return View();
        }

        [HttpPost]
        public JsonResult InviteUsers(string usersToAdd)
        {
            if (!ConnectedUserHelper.IsAdmin && !ConnectedUserHelper.IsTeacher) return null;

            int numberMailsSent = 0;
            if (!string.IsNullOrEmpty(usersToAdd))
            {
                string posted = usersToAdd.Replace('\n', ',').Replace(';', ',').Replace(" ", "").Replace("\r", "");
                string[] mails = posted.Split(',');

                foreach (var mail in mails)
                {
                    if (string.IsNullOrEmpty(mail))
                        continue;

                    Guid idInvite = Guid.NewGuid();
                    string mailSubject = Resources.Intercamber.UserAdmin_InviteMailSubject;
                    string mailBody = string.Format(Resources.Intercamber.UserAdmin_InviteMailBody,
                        Request.Url.ToString().Replace("Admin/InviteUsers", "") + "Account/Create/" + idInvite);
                    bool sent = MailHelper.SendMail(mail, mailSubject, mailBody);
                    numberMailsSent += sent ? 1 : 0;
                    UserInvitesDao.Insert(new UserInvite
                    {
                        Email = mail,
                        DateCreation = DateTime.Now,
                        EmailSent = sent,
                        IdEstablishment = ConnectedUserHelper.IdEstablishment ?? 1, // TODO better !! 
                        IdUserCreation = ConnectedUserHelper.ConnectedUserId,
                        InviteId = idInvite,
                        LearnLanguage = ConnectedUserHelper.connectedUserLearnLanguages.FirstOrDefault()
                    });
                }

            }

            return Json(numberMailsSent);
        }

        public JsonResult InvitedUsersData(GridSettings gridSettings)
        {
            if (!ConnectedUserHelper.IsAdmin && !ConnectedUserHelper.IsTeacher) return null;

            var data = UserInvitesDao.ListUserInvites(gridSettings, ConnectedUserHelper.ConnectedUserId);
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        #endregion

        #region establishment management

        public ActionResult Establishment()
        {
            if (!ConnectedUserHelper.IsAdmin) return RedirectToAction("Login", "Account");
            ViewBag.AllCountries = CountryHelper.AllCountries;
            return View();
        }

        [HttpPost]
        public JsonResult DeleteEstablishment(int idEstablishment)
        {
            if (!ConnectedUserHelper.IsAdmin) return null;

            EstablishmentDao.DeleteEstablishment(idEstablishment);
            SessionHelper.ResetSessionItem(SessionHelper.SessionKeyEstablishments);
            return Json(true);
        }

        [HttpPost]
        public JsonResult UpdateEstablishment(Establishments e)
        {
            if (!ConnectedUserHelper.IsAdmin) return null;

            EstablishmentDao.UpdateEstablishment(e);
            SessionHelper.ResetSessionItem(SessionHelper.SessionKeyEstablishments);
            return Json(true);
        }

        [HttpPost]
        public JsonResult AddEstablishment(Establishments e)
        {
            if (!ConnectedUserHelper.IsAdmin) return null;

            EstablishmentDao.InsertEstablishment(e);
            SessionHelper.ResetSessionItem(SessionHelper.SessionKeyEstablishments);
            return Json(true);
        }

        public JsonResult EstablishmentsData(GridSettings gridSettings)
        {
            if (!ConnectedUserHelper.IsAdmin) return null;

            List<EstablishmentsDetail> data = EstablishmentDao.ListEstablishments();
            data.ForEach(x => x.LabelCountry = ResourcesHelper.GetString("Countries_" + x.IdCountry));
            var res = new GridData<EstablishmentsDetail>
            {
                page = 1, // number of requested page
                records = data.Count, // total records from query 
                total = 1, // total pages of query 
                rows = data
            };
            return Json(res, JsonRequestBehavior.AllowGet);
        }

        #endregion

        #region users management
        public ActionResult Users()
        {
            if (!(ConnectedUserHelper.IsAdmin || ConnectedUserHelper.IsTeacher)) return RedirectToAction("Login", "Account");
            ViewBag.ButtonAddVisible = ConnectedUserHelper.IsAdmin;
            ViewBag.AllCountries = CountryHelper.AllCountries;
            ViewBag.AllProfils = ConnectedUserHelper.IsTeacher ? new List<IdLabel> { ProfilsConst.Student }
                : new List<IdLabel> { ProfilsConst.Admin, ProfilsConst.Teacher, ProfilsConst.Student };
            ViewBag.AllEstablishments = EstablishmentDao.ListEstablishments()
                .Where(x => ConnectedUserHelper.IsAdmin || x.IdEstablishment == ConnectedUserHelper.ConnectedUser.IdEstablishment)
                .Select(x => new IdLabel
                    {
                        Id = x.IdEstablishment,
                        Label = x.LblEstablishment + " (" + x.IdCountry + ")"
                    }).ToList();
            return View();
        }

        public JsonResult UsersData(GridSettings gridSettings, int? idProfil, string name, int? idEstablishment)
        {
            if (!(ConnectedUserHelper.IsAdmin || ConnectedUserHelper.IsTeacher)) return null;
            long? userCreated = null;
            if (ConnectedUserHelper.IsTeacher)
                userCreated = ConnectedUserHelper.ConnectedUserId;
            if (ConnectedUserHelper.IsTeacher)
                idProfil = ProfilsConst.Student.Id;
            var data = UsersDao.ListUsersForAdmin(gridSettings, idProfil, name, userCreated, idEstablishment);
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult UpdateUser(UserAdminDetail u)
        {
            if (!(ConnectedUserHelper.IsAdmin || ConnectedUserHelper.IsTeacher)) return null;
            UsersDao.UpdateUser(u);
            return Json(null);
        }

        [HttpPost]
        public JsonResult AddUser(UserAdminDetail u)
        {
            if (!ConnectedUserHelper.IsAdmin) return null;
            bool res = UsersDao.AddUser(u);
            return Json(!res ? Resources.Intercamber.Error_CannotAddUser : null);
        }


        #endregion

        #region news management
        public ActionResult News()
        {
            if (!ConnectedUserHelper.IsTeacher && !ConnectedUserHelper.IsAdmin) return RedirectToAction("Login", "Account");

            var connecteduser = ConnectedUserHelper.ConnectedUser;

            ViewBag.AllEstablishments = EstablishmentDao.ListEstablishments().Select(x => new IdLabel
            {
                Id = x.IdEstablishment,
                Label = x.LblEstablishment + " (" + x.IdCountry + ")"
            }).ToList();
            ViewBag.AllLanguages = LanguageHelper.AllLanguages.Select(x => new CodeLabel
            {
                Id = x.IdLanguage,
                Label = Resources.Intercamber.ResourceManager.GetString("Languages_" + x.IdLanguage)
            }).ToList();
            ViewBag.EstablishmentRestriction = connecteduser.IsTeacher ? connecteduser.IdEstablishment : null;
            return View();
        }

        public JsonResult NewsData(GridSettings gridSettings)
        {
            if (!ConnectedUserHelper.IsTeacher && !ConnectedUserHelper.IsAdmin) return null;

            Users user = ConnectedUserHelper.ConnectedUser;
            List<NewsDetail> data = NewsDao.ListNews(user);
            var res = new GridData<NewsDetail>
            {
                page = 1, // number of requested page
                records = data.Count, // total records from query 
                total = 1, // total pages of query 
                rows = data
            };
            return Json(res, JsonRequestBehavior.AllowGet);
        }


        [HttpPost]
        public JsonResult AddUpdateNews(News n)
        {
            if (!ConnectedUserHelper.IsTeacher && !ConnectedUserHelper.IsAdmin) return null;

            var user = ConnectedUserHelper.ConnectedUser;
            NewsDao.AddUpdateNews(n, user);
            return Json(true);
        }

        [HttpPost]
        public JsonResult DeleteNews(int idNews)
        {
            if (!ConnectedUserHelper.IsTeacher && !ConnectedUserHelper.IsAdmin) return null;

            var user = ConnectedUserHelper.ConnectedUser;
            NewsDao.DeleteNews(idNews, user);
            return Json(true);
        }

        [HttpPost]
        public ActionResult UploadNewsImage(string CKEditor, string CKEditorFuncNum, string langCode, HttpPostedFileBase upload)
        {
            string file = System.IO.Path.GetFileName(upload.FileName);
            string fileName = Server.MapPath("~/Images/_upload_") + "\\News\\" + file;
            var scaledImage = ImageHelper.ScaleImage(Image.FromStream(upload.InputStream, true, true), 200, 200);
            scaledImage.Save(fileName, ImageFormat.Png);

            string url = "/Images/_upload_/News/" + file;
            return Content("<script>window.parent.CKEDITOR.tools.callFunction(" + CKEditorFuncNum + ", \"" + url + "\");</script>");
        }

        #endregion

        #region moderation management

        public ActionResult Moderation()
        {
            if (!(ConnectedUserHelper.IsAdmin || ConnectedUserHelper.IsTeacher)) return RedirectToAction("Login", "Account");

            ViewBag.AllCountries = CountryHelper.AllCountries;
            return View();
        }

        public JsonResult ModerationData(GridSettings gridSettings)
        {
            if (!(ConnectedUserHelper.IsAdmin || ConnectedUserHelper.IsTeacher)) return null;

            GridData<ModerationDetail> data = ModerationDao.ListModerations(gridSettings, ConnectedUserHelper.ConnectedUser);
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult UpdateModeration(Moderation m)
        {
            if (!ConnectedUserHelper.IsTeacher && !ConnectedUserHelper.IsAdmin) return null;
            var user = ConnectedUserHelper.ConnectedUser;
            ModerationDao.AddUpdateModeration(m, user);
            return Json(true);
        }

        [HttpPost]
        public JsonResult ModerationBlockUser(long idUser, string comment)
        {
            if (!ConnectedUserHelper.IsTeacher && !ConnectedUserHelper.IsAdmin) return null;
            UsersDao.BlockUser(idUser, comment);
            return Json(true);
        }


        #endregion

        #region Statistics

        public ActionResult Statistics()
        {
            if (!ConnectedUserHelper.IsAdmin) return RedirectToAction("Login", "Account");

            ViewBag.NbUserConnected = ChatHub.ListUserConnected.Count;

            return View();
        }

        [HttpPost]
        public JsonResult StatisticsConnectionData(DateTime from, DateTime to, string detail)
        {
            if (!ConnectedUserHelper.IsAdmin) return null;
            var res = StatsDao.StatsConnection(from, to, detail).Select(x => new List<object> { x.Date, x.Number }).ToList();
            return Json(res);
        }

        #endregion
    }
}
